除了ARC之外,另外需要提到的就是理解Reference cycle。
對於單個物件,ARC會自動幫我們釋放記憶體。但多個物件互相引用時,指向彼此strong reference會變成Reference Cycle,ARC無法自動釋放他們。
除了ARC之外,另外需要提到的就是理解Reference cycle。
對於單個物件,ARC會自動幫我們釋放記憶體。但多個物件互相引用時,指向彼此strong reference會變成Reference Cycle,ARC無法自動釋放他們。
Reference Cycle是指物件是由其他物件組成,當被參考的物件被釋放時,我們觀察記憶體實際上卻沒有釋放空間。
class Zoo{
var Owner: String
init (Owner :String){
self.Owner = Owner
print("\(Owner)'zoo is init.")
}
deinit {
print("\(Owner)'zoo is deinit.")
}
}
var leo :Zoo? = Zoo(Owner: "Leo")
//Leo'zoo is init.
leo = nil
//Leo'zoo is deinit.
class Animal{
var animalSpecies :String
init(animalSpecies: String) {
self.animalSpecies = animalSpecies
print("\(animalSpecies) is init.")
}
var belong: Zoo?
deinit {
print("\(animalSpecies) is deinit.")
}
}
class Zoo{
var owner: String
init (owner: String){
self.owner = owner
print("\(owner)'zoo is init.")
}
var ownership: Animal?
deinit {
print("\(owner)'zoo is deinit.")
}
}
var leo: Zoo? = Zoo(owner: "Leo")
var lion: Animal? = Animal(animalSpecies: "lion")
leo?.ownership = lion
lion?.belong = leo
leo = nil
//Leo'zoo is init.
//lion is init.
這邊創造了兩個物件leo還有lion,物件Animal只有一個property是animalSpecies。實例化的lion就是參考animal。把leo設定為nil時卻沒有print出(Owner)'zoo is init.表示記憶體沒有被釋放,這就是Reference Cycle。
實例化Zoo時,記憶體創造了一個記憶體空間,裡面存放Leo,用變數leo儲存。創建Animal時,將lion指到Zoo這個物件上。
所以當leo = nil時 Zoo這個物件還依然被參考,所以Leo'zoo is deinit.這段程式碼並不會被print出來